package com.tankbattle.stage.body.tank;

import com.tankbattle.enums.DirectionEnum;
import com.tankbattle.enums.PowerEnum;
import com.tankbattle.enums.TankTypeEnum;
import com.tankbattle.stage.Stage;
import com.tankbattle.stage.body.Bullet;

import java.util.concurrent.CopyOnWriteArrayList;

import static com.tankbattle.enums.DirectionEnum.DOWN;
import static com.tankbattle.enums.PowerEnum.NO_POWER;
import static com.tankbattle.enums.TankTypeEnum.ORDINARY_ENEMY;


// 3.0
public class Enemy extends Tank implements Runnable {
    /**
     * type
     * 1: 普通的坦克
     * 2: 2和3是同一种类型的坦克（肉盾坦克的不同血量）
     * 4: 飞速坦克
     */
    TankTypeEnum type = ORDINARY_ENEMY;

    CopyOnWriteArrayList<Bullet> bulletPool;
    /**
     * 一些坦克杀死后有奖励
     * 0: 没奖励
     * 1： 获得时间暂停
     * 2: 加一条命
     * 3: 所有坦克上西天
     * 4: 获得保护盾
     * 5: 吃三次星星（每颗有额外加分）子弹加速、子弹穿钢铁
     * 6: 基地获得建筑变成
     */
    // TODO: 实现道具
    PowerEnum award;
    long extTime;


    public Enemy(int x, int y) {
        super(x, y);
        this.life = 1;
        this.award = NO_POWER;
        this.bulletPool = new CopyOnWriteArrayList<>();
        this.alive = true;
        this.setDirection(DOWN);
        this.setSpeed(8);
        this.moving = true;
        this.type = ORDINARY_ENEMY;
        this.setFlag(1);
        // to show born gif. new a enemy needs unvisual
        this.visible = false;
        this.extTime = System.currentTimeMillis();
    }

    @Override
    public boolean isAlive() {
        return alive;
    }

    @Override
    public void setAlive(boolean alive) {
        this.alive = alive;
    }

    // AI tank 5.0..
    @Override
    public void run() {

        int fire = 0;
        while (true) {
            Bullet bullet = null;
            try {
                Thread.sleep(15);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //touch the wall stop
            switch (this.getDirection()) {
                case UP:
                    for (int from = 0; from < 4; from++) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!this.isMoving()) {
                            break;
                        }
                        if (this.getY() > 0) {
                            this.setY(this.getY() - this.getSpeed());
                        } else {
                            break;
                        }
                    }
                    break;
                case LEFT:
                    for (int from = 0; from < 4; from++) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!this.isMoving()) {
                            break;
                        }
                        if (this.getX() > 0) {
                            this.setX(this.getX() - this.getSpeed());
                        } else {
                            break;
                        }
                    }
                    break;
                case DOWN:
                    for (int from = 0; from < 4; from++) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!this.isMoving()) {
                            break;
                        }
                        if (this.getY() < 520 - 32) {
                            this.setY(this.getY() + this.getSpeed());
                        } else {
                            break;
                        }
                    }
                    break;
                case RIGHT:
                    for (int from = 0; from < 4; from++) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!this.isMoving()) {
                            break;
                        }
                        if (this.getX() < 520 - 32) {
                            this.setX(this.getX() + this.getSpeed());
                        } else {
                            break;
                        }
                    }
                    break;
                default:
                    break;
            }
            fire = (int) (Math.random() * 2);
            if (this.isAlive() && this.isMoving() && (fire == 1)) {
                switch (this.getDirection()) {
                    case UP:
                        bullet = new Bullet(getX() + 12, getY() - 8, DOWN);
                        break;
                    case LEFT:
                        bullet = new Bullet(getX() - 8, getY() + 12, DirectionEnum.LEFT);
                        break;
                    case DOWN:
                        bullet = new Bullet(getX() + 12, getY() + 32, DirectionEnum.UP);
                        break;
                    case RIGHT:
                        bullet = new Bullet(getX() + 32, getY() + 12, DirectionEnum.RIGHT);
                        break;
                    default:
                        break;
                }
                bullet.setType(1);
                this.bulletPool.add(bullet);
                Thread thread = new Thread(bullet);
                thread.start();

            }

            if (this.isMoving()) {
                DirectionEnum dir = DirectionEnum.randomDirection();
                this.setDirection(dir);
            }
            //DIE
            if (!this.isAlive()) {
                // kill the thread directly and then release
                for (int i = 0; i < 32; i++) {
                    for (int j = 0; j < 32; j++) {
                        if (tanks[this.getX() + i][this.getY() + j] == 1) {
                            tanks[this.getX() + i][this.getY() + j] = 0;
                        }
                    }
                }
                break;
            }
            if (Stage.gameOver) {
                break;
            }
        }

    }


    public TankTypeEnum getType() {
        return type;
    }

    public void setType(TankTypeEnum type) {
        this.type = type;
    }

    public CopyOnWriteArrayList<Bullet> getBulletPool() {
        return bulletPool;
    }

    public void setBulletPool(CopyOnWriteArrayList<Bullet> bulletPool) {
        this.bulletPool = bulletPool;
    }

    public PowerEnum getAward() {
        return award;
    }

    public void setAward(PowerEnum award) {
        this.award = award;
    }

    public int getWhenBornPaintTimes() {
        return whenBornPaintTimes;
    }

    public void setWhenBornPaintTimes(int whenBornPaintTimes) {
        this.whenBornPaintTimes = whenBornPaintTimes;
    }

    public long getExtTime() {
        return extTime;
    }

    public void setExtTime(long extTime) {
        this.extTime = extTime;
    }
}
